package spu

import (
	"context"
	"gorm.io/gorm"
	"mall/common/excption"
	constans "mall/services/product/rpc/consts"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/mapper"
	"mall/services/product/rpc/internal/mapper/entity"
	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type ManageLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewSpuManageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ManageLogic {
	return &ManageLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *ManageLogic) SpuManage(in *pb.SpuManageDTO) (*pb.EmptyObj, error) {
	// 1.check request dto
	spuMapper, checkErr := l.checkRequestDTO(in)
	if checkErr != nil {
		return nil, checkErr
	}
	// 2.update spu db
	saveErr := l.saveDB(in, spuMapper)
	if saveErr != nil {
		return nil, saveErr
	}
	// 3.return obj
	return &pb.EmptyObj{}, nil
}

func (l *ManageLogic) checkRequestDTO(in *pb.SpuManageDTO) (*mapper.SpuMapper[entity.SpuEntity], error) {
	spuMapper := mapper.NewSpuMapper[entity.SpuEntity]()
	selectCountCtx, err := spuMapper.SelectCountCtx(l.ctx, l.svcCtx.DBEngin, bo.SpuBO{
		SpuIdArr: in.SpuIdArr, NeStatus: constans.SpuTakeDown,
	})
	if err != nil {
		return nil, err
	}
	if int(selectCountCtx) != len(in.SpuIdArr) {
		return nil, excption.NewErrCode(constans.SpuInfoNoExistError)
	}
	return spuMapper, nil
}

func (l *ManageLogic) saveDB(in *pb.SpuManageDTO, spuMapper *mapper.SpuMapper[entity.SpuEntity]) error {
	// 提取spuId
	skuMapper := mapper.NewSkuMapper()
	saveErr := l.svcCtx.DBEngin.Transaction(func(tx *gorm.DB) error {
		updateSpuErr := spuMapper.SpuManageCtx(l.ctx, tx, in.GetSpuIdArr(), int(in.Status))
		if updateSpuErr != nil {
			return updateSpuErr
		}
		updateSkuErr := skuMapper.SkuManageForSpuIdCtx(l.ctx, tx, in.GetSpuIdArr(), int(in.Status))
		if updateSkuErr != nil {
			return updateSkuErr
		}
		return nil
	})
	if saveErr != nil {
		return saveErr
	}
	return nil
}
